package com.rinvay.utils;

import java.io.UnsupportedEncodingException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import android.net.Uri;
import android.webkit.MimeTypeMap;

public class URLUtil
{
    
    public static final String guessFileName2(String url,
            String contentDisposition, String mimeType) {
        String filename = parseContentDisposition(contentDisposition);
        try {
            if(filename != null) {
                filename = new String(filename.getBytes("ISO8859-1"), "gb2312");
            }
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        if(filename == null || filename.trim().equals("")) {
            filename = guessFileName(url, contentDisposition, mimeType);
        }
        return filename;
    }

	/**
	 * Guesses canonical filename that a download would have, using
	 * the URL and contentDisposition. File extension, if not defined,
	 * is added based on the mimetype
	 * @param url Url to the content
	 * @param contentDisposition Content-Disposition HTTP header or null
	 * @param mimeType Mime-type of the content or null
	 * 
	 * @return suggested filename
	 */
	public static final String guessFileName(String url,
			String contentDisposition, String mimeType) {
		String filename = null;
		String extension = null;

		// If we couldn't do anything with the hint, move toward the content disposition
		if (filename == null && contentDisposition != null)
		{
			filename = parseContentDisposition(contentDisposition);
			if (filename != null)
			{
				int index = filename.lastIndexOf('/') + 1;
				if (index > 0)
				{
					filename = filename.substring(index);
				}
			}
		}

		// If all the other http-related approaches failed, use the plain uri
		if (filename == null)
		{
			String decodedUrl = Uri.decode(url);
			if (decodedUrl != null)
			{
				int queryIndex = decodedUrl.indexOf('?');
				// If there is a query string strip it, same as desktop browsers
				if (queryIndex > 0)
				{
					decodedUrl = decodedUrl.substring(0, queryIndex);
				}
				if (!decodedUrl.endsWith("/"))
				{
					int index = decodedUrl.lastIndexOf('/') + 1;
					if (index > 0)
					{
						filename = decodedUrl.substring(index);
					}
				}
			}
		}

		// Finally, if couldn't get filename from URI, get a generic filename
		if (filename == null)
		{
			filename = "downloadfile";
		}

		// Split filename between base and extension
		// Add an extension if filename does not have one
		int dotIndex = filename.indexOf('.');
		if (dotIndex < 0)
		{
			if (mimeType != null)
			{
				extension = MimeTypeMap.getSingleton()
						.getExtensionFromMimeType(mimeType);
				if (extension != null)
				{
					extension = "." + extension;
				}
			}
			if (extension == null)
			{
				if (mimeType != null
						&& mimeType.toLowerCase().startsWith("text/"))
				{
					if (mimeType.equalsIgnoreCase("text/html"))
					{
						extension = ".html";
					}
					else
					{
						extension = ".txt";
					}
				}
				else
				{
					extension = ".bin";
				}
			}
		}
		else
		{
			if (mimeType != null)
			{
				// Compare the last segment of the extension against the mime type.
				// If there's a mismatch, discard the entire extension.
				int lastDotIndex = filename.lastIndexOf('.');
				String typeFromExt = MimeTypeMap.getSingleton()
						.getMimeTypeFromExtension(
								filename.substring(lastDotIndex + 1));
				if (typeFromExt != null
						&& !typeFromExt.equalsIgnoreCase(mimeType))
				{
					extension = MimeTypeMap.getSingleton()
							.getExtensionFromMimeType(mimeType);
					if (extension != null)
					{
						extension = "." + extension;
					}
				}
			}
			if (extension == null)
			{
				extension = filename.substring(dotIndex);
			}
			filename = filename.substring(0, dotIndex);
		}

		return filename + extension;
	}

	/** Regex used to parse content-disposition headers */
	private static final Pattern CONTENT_DISPOSITION_PATTERN = Pattern.compile(
			"attachment;\\s*filename\\s*=\\s*(\"?)([^\"]*)\\1\\s*$",
			Pattern.CASE_INSENSITIVE);

	/*
	 * Parse the Content-Disposition HTTP Header. The format of the header
	 * is defined here: http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html
	 * This header provides a filename for content that is going to be
	 * downloaded to the file system. We only support the attachment type.
	 * Note that RFC 2616 specifies the filename value must be double-quoted.
	 * Unfortunately some servers do not quote the value so to maintain
	 * consistent behaviour with other browsers, we allow unquoted values too.
	 */
	static String parseContentDisposition(String contentDisposition) {
		try
		{
			Matcher m = CONTENT_DISPOSITION_PATTERN.matcher(contentDisposition);
			if (m.find())
			{
				return m.group(2);
			}
		} catch (IllegalStateException ex)
		{
			// This function is defined as returning null when it can't parse the header
		}
		return null;
	}
}
